package com.mc.book.controller;

import com.alibaba.fastjson2.JSONObject;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
import com.github.binarywang.wxpay.bean.request.*;
import com.github.binarywang.wxpay.bean.result.*;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.mc.book.enums.ResponseEnum;
import com.mc.book.pojo.Result;
import com.mc.book.pojo.request.RequestPay;
import com.mc.book.pojo.request.RequestUser;
import com.mc.book.service.PayService;
import com.mc.book.service.UserService;
import com.mc.book.utils.IpUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.TimeUnit;


/**
 * @author Binary Wang
 */
@Api("微信支付")
@RestController
@RequestMapping("/pay")
@AllArgsConstructor
public class WxPayController extends BaseApi{
    private static final Logger log = LoggerFactory.getLogger(WxPayController.class);
    private WxPayService wxService;
    @Autowired
    private UserService userService;
    @Autowired
    private PayService payService;
    @Autowired
    private HttpServletRequest httpServletRequest;

    /**
     * 调用统一下单接口，并组装生成支付所需参数对象.
     *
     * @param request 统一下单请求参数
     * @param <T>     请使用{@link com.github.binarywang.wxpay.bean.order}包下的类
     * @return 返回 {@link com.github.binarywang.wxpay.bean.order}包下的类对象
     */
    @ApiOperation(value = "统一下单，并组装所需支付参数")
    @PostMapping("/createOrder")
    public Result createOrder(@RequestBody  WxPayUnifiedOrderRequest request)  {
        Integer price = 0;
        try {
            request.setOutTradeNo(UUID.randomUUID().toString().replace("-",""));
            request.setSpbillCreateIp(IpUtil.getIp(httpServletRequest));

            String attach = request.getAttach();
            JSONObject json = JSONObject.parseObject(attach);
            if(null == json) return Result.fail();

            Integer goods_type = json.getInteger("goods_type");
            String user_phone = json.getString("user_phone");
            String token = json.getString("token");

            if(null == goods_type) return Result.fail();
            if(null == user_phone) return Result.fail();
            if(null == token) return Result.fail();

            //月卡会员
            if(1 == goods_type) price = 2000;
            //年卡
            if(2 == goods_type) price = 20000;
            //防篡改会员价格
            if(!request.getTotalFee().equals(price)) return Result.fail();
            return Result.success(this.wxService.createOrder(request));
        }catch (Exception e){
            log.error("系统异常：", e);
            return Result.fail(ResponseEnum.UP_SYSTEM_FAILURE.getCode(),ResponseEnum.UP_SYSTEM_FAILURE.getMessage());
        }
    }

    @ApiOperation(value = "支付回调通知处理")
    @PostMapping("/notify/order")
    public String parseOrderNotifyResult(@RequestBody String xmlData) throws WxPayException {
        Integer price = 0;
        RequestUser user = new RequestUser();
        RequestPay pay = new RequestPay();

        final WxPayOrderNotifyResult notifyResult = this.wxService.parseOrderNotifyResult(xmlData);
        System.out.println(notifyResult.toString());

        String attach = notifyResult.getAttach();
        JSONObject json = JSONObject.parseObject(attach);

        if(null != json){
            String user_phone = json.getString("user_phone");
            Integer goods_type = json.getInteger("goods_type");
            String token = json.getString("token");

            user.setUser_phone(user_phone);
            user.setToken(token);

            pay.setUser_phone(user_phone);
            pay.setGoods_type(goods_type);
            pay.setTotal_fee(notifyResult.getTotalFee());
            pay.setPay_content(notifyResult.toString());
            pay.setCreate_time(new Date());
            payService.insertPay(pay);


            if(1 == goods_type){
                price = 2000;
                if(notifyResult.getTotalFee().equals(price)){
                    userService.vipUpdate(user,goods_type);
                }
            }


            if(2 == goods_type){
                price = 20000;
                if(notifyResult.getTotalFee().equals(price)){
                    userService.vipUpdate(user,goods_type);
                }
            }



        }

        // TODO 根据自己业务场景需要构造返回对象
        return WxPayNotifyResponse.success("成功");
    }


    /**
     * <pre>
     * 微信支付-申请退款
     * 详见 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
     * 接口链接：https://api.mch.weixin.qq.com/secapi/pay/refund
     * </pre>
     *
     * @param request 请求对象
     * @return 退款操作结果
     */
    @ApiOperation(value = "退款")
    @PostMapping("/refund")
    public WxPayRefundResult refund(@RequestBody WxPayRefundRequest request) throws WxPayException {
        return this.wxService.refund(request);
    }

    @ApiOperation(value = "退款回调通知处理")
    @PostMapping("/notify/refund")
    public String parseRefundNotifyResult(@RequestBody String xmlData) throws WxPayException {
        final WxPayRefundNotifyResult result = this.wxService.parseRefundNotifyResult(xmlData);
        // TODO 根据自己业务场景需要构造返回对象
        return WxPayNotifyResponse.success("成功");
    }


    /**
     * <pre>
     * 撤销订单API
     * 文档地址：https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_11&index=3
     * 应用场景：
     *  支付交易返回失败或支付系统超时，调用该接口撤销交易。如果此订单用户支付失败，微信支付系统会将此订单关闭；如果用户支付成功，微信支付系统会将此订单资金退还给用户。
     *  注意：7天以内的交易单可调用撤销，其他正常支付的单如需实现相同功能请调用申请退款API。提交支付交易后调用【查询订单API】，没有明确的支付结果再调用【撤销订单API】。
     *  调用支付接口后请勿立即调用撤销订单API，建议支付后至少15s后再调用撤销订单接口。
     *  接口链接 ：https://api.mch.weixin.qq.com/secapi/pay/reverse
     *  是否需要证书：请求需要双向证书。
     * </pre>
     */
    @ApiOperation(value = "撤销订单")
    @PostMapping("/reverseOrder")
    public WxPayOrderReverseResult reverseOrder(@RequestBody WxPayOrderReverseRequest request) throws WxPayException {
        return this.wxService.reverseOrder(request);
    }



}